__author__      = "Michael Kunkelmann"
__copyright__   = "Copyright 2017, Linde Material Handling GmbH"
__version__     = "0.0.1"
__email__       = "michael.kunkelmann@lind-mh.de"
__status__      = "Prototype"
__date__        = "xxxx-xx-xx"


import ctypes


########################################
# driver status
XL_SUCCESS                     = 0   #=0x0000
XL_PENDING                     = 1   #=0x0001

XL_ERR_QUEUE_IS_EMPTY          = 10  #=0x000A
XL_ERR_QUEUE_IS_FULL           = 11  #=0x000B
XL_ERR_TX_NOT_POSSIBLE         = 12  #=0x000C
XL_ERR_NO_LICENSE              = 14  #=0x000E
XL_ERR_WRONG_PARAMETER         = 101 #=0x0065
XL_ERR_TWICE_REGISTER          = 110 #=0x006E
XL_ERR_INVALID_CHAN_INDEX      = 111 #=0x006F
XL_ERR_INVALID_ACCESS          = 112 #=0x0070
XL_ERR_PORT_IS_OFFLINE         = 113 #=0x0071
XL_ERR_CHAN_IS_ONLINE          = 116 #=0x0074
XL_ERR_NOT_IMPLEMENTED         = 117 #=0x0075
XL_ERR_INVALID_PORT            = 118 #=0x0076
XL_ERR_HW_NOT_READY            = 120 #=0x0078
XL_ERR_CMD_TIMEOUT             = 121 #=0x0079
XL_ERR_HW_NOT_PRESENT          = 129 #=0x0081
XL_ERR_NOTIFY_ALREADY_ACTIVE   = 131 #=0x0083
XL_ERR_NO_RESOURCES            = 152 #=0x0098
XL_ERR_WRONG_CHIP_TYPE         = 153 #=0x0099
XL_ERR_WRONG_COMMAND           = 154 #=0x009A
XL_ERR_INVALID_HANDLE          = 155 #=0x009B
XL_ERR_CANNOT_OPEN_DRIVER      = 201 #=0x00C9
XL_ERR_WRONG_BUS_TYPE          = 202 #=0x00CA
XL_ERR_DLL_NOT_FOUND           = 203 #=0x00CB

# special stream defines
XL_ERR_CONNECTION_BROKEN       = 210 #=0x00D2
XL_ERR_CONNECTION_CLOSED       = 211 #=0x00D3
XL_ERR_INVALID_STREAM_NAME     = 212 #=0x00D4
XL_ERR_CONNECTION_FAILED       = 213 #=0x00D5
XL_ERR_STREAM_NOT_FOUND        = 214 #=0x00D6
XL_ERR_STREAM_NOT_CONNECTED    = 215 #=0x00D7
XL_ERR_QUEUE_OVERRUN           = 216 #=0x00D8
XL_ERROR                       = 255 #=0x00FF


XL_HWTYPE_NONE                        = 0
XL_HWTYPE_VIRTUAL                     = 1
XL_HWTYPE_CANCARDX                    = 2
XL_HWTYPE_CANCARDXL                   = 15
XL_HWTYPE_CANAC2PCI                   = 6

XL_HWTYPE_CANCARDY                    =  12
XL_HWTYPE_CANCASEXL                   =  21
XL_HWTYPE_CANCASEXL_LOG_OBSOLETE      =  23
XL_HWTYPE_CANBOARDXL                  =  25
XL_HWTYPE_CANBOARDXL_PXI              =  27
XL_HWTYPE_VN2600                      =  29
XL_HWTYPE_VN2610                      =  29  
XL_HWTYPE_VN3300                      =  37
XL_HWTYPE_VN3600                      =  39
XL_HWTYPE_VN7600                      =  41
XL_HWTYPE_CANCARDXLE                  =  43
XL_HWTYPE_VN8900                      =  45
XL_HWTYPE_VN2640                      =  53
XL_HWTYPE_VN1610                      =  55
XL_HWTYPE_VN1630                      =  57
XL_HWTYPE_VN1640                      =  59
XL_HWTYPE_VN1611                      =  63

XL_BUS_TYPE_NONE               = 0
XL_BUS_TYPE_CAN                = 1

XL_INTERFACE_VERSION           = 3

XL_INVALID_PORTHANDLE          = -1

XL_ACTIVATE_NONE               = 0
XL_ACTIVATE_RESET_CLOCK        = 8

#definitions for the events and commands used by the driver
XL_NO_COMMAND                  =  0
XL_RECEIVE_MSG                 =  1
XL_CHIP_STATE                  =  4
XL_TRANSCEIVER                 =  6
XL_TIMER                       =  8
XL_TRANSMIT_MSG                = 10
XL_SYNC_PULSE                  = 11
XL_APPLICATION_NOTIFICATION    = 15

#for LIN we have special events
XL_LIN_MSG                     = 20
XL_LIN_ERRMSG                  = 21
XL_LIN_SYNCERR                 = 22
XL_LIN_NOANS                   = 23
XL_LIN_WAKEUP                  = 24
XL_LIN_SLEEP                   = 25
XL_LIN_CRCINFO                 = 26
                                 
# for D/A IO bus                 
XL_RECEIVE_DAIO_DATA           = 32

XL_BUS_TYPE_NONE               = 0x00000000
XL_BUS_TYPE_CAN                = 0x00000001
XL_BUS_TYPE_LIN                = 0x00000002
XL_BUS_TYPE_FLEXRAY            = 0x00000004
XL_BUS_TYPE_MOST               = 0x00000010
XL_BUS_TYPE_DAIO               = 0x00000040 # IO cab
XL_BUS_TYPE_HWSYNC             = 0x00000080
XL_BUS_TYPE_J1708              = 0x00000100

XL_CHIPSTAT_BUSOFF              = 0x01
XL_CHIPSTAT_ERROR_PASSIVE       = 0x02
XL_CHIPSTAT_ERROR_WARNING       = 0x04
XL_CHIPSTAT_ERROR_ACTIVE        = 0x08

XL_CAN_STATE_FLAG_SJA_MODE      = 0x00000001

# ctypes type 	C type 	                                    Python type
# c_bool 	    _Bool 	                                    bool (1)
# c_char 	    char 	                                    1-character string
# c_wchar 	    wchar_t 	                                1-character unicode string
# c_byte 	    char 	                                    int/long
# c_ubyte 	    unsigned                                    char 	int/long
# c_short 	    short 	                                    int/long
# c_ushort 	    unsigned                                    short 	int/long
# c_int 	    int 	                                    int/long
# c_uint 	    unsigned int 	                            int/long
# c_long 	    long 	                                    int/long
# c_ulong 	    unsigned long 	                            int/long
# c_longlong 	__int64 or long long 	                    int/long
# c_ulonglong   unsigned __int64 or unsigned long long 	    int/long
# c_float 	    float 	                                    float
# c_double 	    double 	                                    float
# c_longdouble 	long double 	                            float
# c_char_p 	    char * (NUL terminated) 	                string or None
# c_wchar_p 	wchar_t * (NUL terminated) 	                unicode or None
# c_void_p 	    void * 	                                    int/long or None

XL_U64   = ctypes.c_ulonglong
XL_U32   = ctypes.c_ulong
XL_U16   = ctypes.c_ushort
XL_U8    = ctypes.c_ubyte

XL_S64   = ctypes.c_longlong
XL_S32   = ctypes.c_long
XL_S16   = ctypes.c_short
XL_S8    = ctypes.c_byte


XLuint64 = ctypes.c_ulonglong
XLAccess = XLuint64
XLStatus = ctypes.c_short
XLHandle = ctypes.c_long
XLEventtag = ctypes.c_ubyte

MAX_MSG_LEN = 8
class s_xl_can_msg( ctypes.Structure ):
    _fields_ = [( 'id'     , XL_U32              ),     #unsigned long     id;
                ( 'flags'  , XL_U16              ),     #unsigned short    flags;
                ( 'dlc'    , XL_U16              ),     #unsigned short    dlc;
                ( 'res1'   , XL_U64              ),     #XLuint64          res1;
                ( 'data'   , XL_U8 * MAX_MSG_LEN ),     #unsigned char     data [MAX_MSG_LEN];
                ( 'res2'   , XL_U64              )]     #XLuint64          res2;
       
       
class s_xl_chip_state( ctypes.Structure ):
    _fields_ = [( 'busStatus'     , XL_U8   ),           #unsigned char busStatus;
                ( 'txErrorCounter', XL_U8   ),           #unsigned char txErrorCounter;
                ( 'rxErrorCounter', XL_U8   ),           #unsigned char rxErrorCounter;
                ( 'chipState'     , XL_U8   ),           #unsigned char chipState;
                ( 'flags'         , ctypes.c_uint )]     #unsigned int  flags;
                
                
# LIN event structures 
class s_xl_lin_msg( ctypes.Structure ):
    _fields_ = [( 'id',    XL_U8       ),                #unsigned char id;
                ( 'dlc',   XL_U8       ),                #unsigned char dlc;
                ( 'flags', XL_U16      ),                #unsigned short flags;
                ( 'data',  XL_U8 * 8   ),                #unsigned char data[8];
                ( 'crc',   XL_U8       )]                #unsigned char crc;


class s_xl_lin_sleep( ctypes.Structure ):
    _fields_ = [( 'flag', XL_U8 )]                       #unsigned char flag;
    

class s_xl_lin_no_ans( ctypes.Structure ):
    _fields_ = [( 'id', XL_U8 )]                         #unsigned char id;


class s_xl_lin_wake_up( ctypes.Structure ):
    _fields_ = [( 'flag', XL_U8 )]                       #unsigned char flag;


class s_xl_lin_crc_info( ctypes.Structure ):
    _fields_ = [( 'id', XL_U8    ),                       #unsigned char id;
                ( 'flags', XL_U8 )]                       #unsigned char flags;


# LIN messages structure
class s_xl_lin_msg_api( ctypes.Structure ):
    _fields_ = [( 'linMsg'    , s_xl_lin_msg     ),       #struct s_xl_lin_msg          linMsg; 
                ( 'linNoAns'  , s_xl_lin_no_ans  ),       #struct s_xl_lin_no_ans       linNoAns;
                ( 'linWakeUp' , s_xl_lin_wake_up ),       #struct s_xl_lin_wake_up      linWakeUp;
                ( 'linSleep'  , s_xl_lin_sleep   ),       #struct s_xl_lin_sleep        linSleep;
                ( 'linCRCinfo', s_xl_lin_crc_info)]       #struct s_xl_lin_crc_info     linCRCinfo;

                
                
XL_DAIO_DATA_GET                     = 0x8000
XL_DAIO_DATA_VALUE_DIGITAL           = 0x0001
XL_DAIO_DATA_VALUE_ANALOG            = 0x0002
XL_DAIO_DATA_PWM                     = 0x0010
XL_DAIO_MODE_PULSE                   = 0x0020  # generates pulse in values of PWM 

class s_xl_daio_data( ctypes.Structure ):
    _fields_ = [( 'flags'                , XL_U16            ),       #unsigned short    flags;                 // 2
                ( 'timestamp_correction' , ctypes.c_uint     ),       #unsigned int      timestamp_correction;  // 4
                ( 'mask_digital'         , XL_U8             ),       #unsigned char     mask_digital;          // 1
                ( 'value_digital'        , XL_U8             ),       #unsigned char     value_digital;         // 1
                ( 'mask_analog'          , XL_U8             ),       #unsigned char     mask_analog;           // 1
                ( 'reserved0'            , XL_U8             ),       #unsigned char     reserved0;             // 1
                ( 'value_analog'         , XL_U16*4          ),       #unsigned short    value_analog[4];       // 8
                ( 'pwm_frequency'        , ctypes.c_uint     ),       #unsigned int      pwm_frequency;         // 4
                ( 'pwm_value'            , XL_U16            ),       #unsigned short    pwm_value;             // 2
                ( 'reserved1'            , ctypes.c_uint     ),       #unsigned int      reserved1;             // 4
                ( 'reserved2'            , ctypes.c_uint     )]       #unsigned int      reserved2;             // 4





#------------------------------------------------------------------------------
# structure for XL_SYNC_PULSE 
#define XL_SYNC_PULSE_EXTERNAL      0x00
#define XL_SYNC_PULSE_OUR           0x01
#define XL_SYNC_PULSE_OUR_SHARED    0x02

class s_xl_sync_pulse( ctypes.Structure ):
    _fields_ = [( 'pulseCode', XL_U8    ),             #unsigned char    pulseCode;                 //!< generated by us
                ( 'time'     , XL_U64   )]             #XLuint64         time;                      //!< 1ns resolution
                
XL_TRANSCEIVER_EVENT_NONE                = 0
XL_TRANSCEIVER_EVENT_INSERTED            = 1           #//!< cable was inserted
XL_TRANSCEIVER_EVENT_REMOVED             = 2           #//!< cable was removed
XL_TRANSCEIVER_EVENT_STATE_CHANGE        = 3           #//!< transceiver state changed

class s_xl_transceiver( ctypes.Structure ):
    _fields_ = [( 'event_reason',  XL_U8   ),           #unsigned char  event_reason;                //!< reason for what was event sent
                ( 'is_present'  ,  XL_U8   )]           #unsigned char  is_present;                  //!< allways valid transceiver presence flag

                
class s_xl_tag_data( ctypes.Union ):
    _fields_ = [( 'msg'        , s_xl_can_msg     ),     #struct s_xl_can_msg              msg;
                ( 'chipState'  , s_xl_chip_state  ),     #struct s_xl_chip_state           chipState;
                ( 'linMsgApi'  , s_xl_lin_msg_api ),     #union  s_xl_lin_msg_api          linMsgApi;
                ( 'syncPulse'  , s_xl_sync_pulse  ),     #struct s_xl_sync_pulse           syncPulse;
                ( 'daioData'   , s_xl_daio_data   ),     #struct s_xl_daio_data            daioData;
                ( 'transceiver', s_xl_transceiver )]     #struct s_xl_transceiver          transceiver;

                
# XL_EVENT structures
# event type definition 

class s_xl_event( ctypes.Structure ):
    _fields_ = [( 'tag'        , XLEventtag    ),        #           tag;             // 1                          
                ( 'chanIndex'  , XL_U8         ),        #unsigned char        chanIndex;       // 1
                ( 'transId'    , XL_U16        ),        #unsigned short       transId;         // 2
                ( 'portHandle' , XL_U16        ),        #unsigned short       portHandle;      // 2 internal use only !!!!
                ( 'reserved'   , XL_U16        ),        #unsigned short       reserved;        // 2
                ( 'timeStamp'  , XL_U64        ),        #XLuint64             timeStamp;       // 8
                ( 'tagData'    , s_xl_tag_data )]        #s_xl_tag_data  tagData;         // 32 Bytes 

XLEvent = s_xl_event
